package SeparateAnalysis;

import com.phidgets.PhidgetException;
import com.phidgets.TemperatureSensorPhidget;
import org.jfree.chart.ChartPanel;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Hashtable;

/**
 * Created by IntelliJ IDEA.
 * User: Mike
 * Date: 11/4/11
 * Time: 5:06 PM
 * To change this template use File | Settings | File Templates.
 * <p/>
 * to create new chart... add a non palette object: ChartPanel.. select both of the check boxes
 */

// todo     ave abv
// todo: plot vaporAbv with corrAbv vs time
// todo: plot abv per bottle    bar chart    - (abv & ml should be done calculating... need to update bar chart)
// todo autoupdate chart
// todo create batch file to start jar with more memory


public class MainGui {

    //} implements Runnable {
    public JPanel ideaGui2;
    private JButton startRecordingButton;
    public JPanel distTempPanel;
    private JPanel recDataPanel;
    private JButton stopRecordingButton;
    private JPanel distDataPanel;
    private JProgressBar progressBar1;
    private JComboBox bottle;
    private JComboBox boilerTemp;
    private JComboBox measAbv;
    private JComboBox distTemp;
    private JTabbedPane Pane1;
    private JEditorPane editorPane1;
    private JButton updateGraphButton;
    private ChartPanel chartPanelBar;
    private ChartPanel chartPanelArea;
    private ChartPanel chartPanelPie;
    private JButton updateButton;
    private JTextField ambientC;
    private JTextField ambientF;
    public JTextField columnC;
    private JTextField columnF;
    private JTextField corrAbv;
    private JTextField vaporAbv;
    private JComboBox flowRateVol;
    private ChartPanel chartPanelTime;
    private JComboBox oG;
    private JComboBox tG;
    private JComboBox oT;
    private JComboBox tT;
    private JPanel wortPanel;
    private JTextField wortAbv;
    private JComboBox chartRange;
    private JComboBox flowRateTime;
    private JTextField flowRate;
    private JTextField chartRangeTxt;
    ChartArea cArea;
    ChartBar cBar;
    ChartPie cPie;
    ChartTime cTime;

    static boolean readIn = false;
    boolean readingTemp = false;

    private Thread tempThread, writeThread;

    static double lastWrittenTemp = 1.1;
    static String lastWrittenBoilTemp = "1.1";
    static String lastWrittenBottleNum = "0";
    static String lastWrittenAbv = "0.0";
    JFrame frame;
    static final Double minTempChangeForWrite = 0.25;

    double columnDC = 92.6;
    double columnDF = 98.6;
    double ambientDC = 98.6;
    double ambientDF = 98.6;
    String boilerSC = "98.6";
    String bottleNumS = "98.6";
    String corrAbvS = "98.6";

    public String getAmbientC() {
        String output = ambientC.getText();
        return output;
    }

    public String getAmbientF() {
        String output = ambientF.getText();
        return output;
    }

    public String getColumnC() {
        String output = columnC.getText();
        return output;
    }

    public String getColumnF() {
        String output = columnF.getText();
        return output;
    }

    public void setAmbientC(String input) {
        if (!input.equals(null))
            ambientC.setText(input);
    }

    public void setAmbientF(String input) {
        if (!input.equals(null))
            ambientF.setText(input);
    }

    public void setColumnC(String input) {
        if (!input.equals(null))
            columnC.setText(input);
    }

    public void setColumnF(String input) {
        if (!input.equals(null))
            columnF.setText(input);
    }

    public void setVaporAbv(String input) {
        if (!input.equals(null))
            vaporAbv.setText(input);
    }

    //	@Override
    public void runIt() {
        JFrame frame = new JFrame("MainGui");
        frame.setContentPane(new MainGui().ideaGui2);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);


    }

    private void createUIComponents() {
        setLook();
        // Set Charts ::::::::::::::::::::::::::::::::
        this.cArea = new ChartArea("Area Chart");
        this.cBar = new ChartBar("Bar Chart");
        this.cPie = new ChartPie("Pie Chart");
        this.cTime = new ChartTime("Time Chart");
        this.chartPanelBar = new ChartPanel(this.cBar.getChart());
        this.chartPanelArea = new ChartPanel(this.cArea.getChart());
        this.chartPanelPie = new ChartPanel(this.cPie.getChart());
        this.chartPanelTime = new ChartPanel(this.cTime.getChart());
    }

    private static void setLook() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            System.out.println("Error setting native LAF: " + e);
        }
    }

    public MainGui() {
        columnC.setBorder(null);
        columnF.setBorder(null);
        ambientC.setBorder(null);
        ambientF.setBorder(null);
        corrAbv.setBorder(null);
        flowRate.setBorder(null);
        chartRangeTxt.setBorder(null);
        vaporAbv.setBorder(null);
        boilerTemp.setSelectedIndex(22);
        distTemp.setSelectedIndex(30);
        flowRateVol.setSelectedIndex(140);
        chartRange.setSelectedIndex(1);

        startRecordingButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                readIn = true;
                System.out.println("start button hit!" + readIn);
                if (!readingTemp)
                    temperature();
                readingTemp = true;
            }
        });
        updateButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                double[][] data = new double[][]{{1.0, 3.0, 3.0, 5.0, 5.0, 5.0, 3.0, 3.0}, {7.0, 7.0, 7.0, 8.0, 8.0, 8.0, 10.0, 10.0}, {4.0, 3.0, 2.0, 3.0, 6.0, 3.0, 4.0, 3.0}};
                cArea.updateChart(data);
                chartPanelArea.setChart(cArea.getChart());
                chartPanelPie.setChart(cPie.getChart2());
                chartPanelPie.validate();
                //---------------------------------------- ColumnT vs time
                ReadInData dataR = new ReadInData();
                dataR.Read();
                cTime.updateChart(dataR.getmilliTime(), dataR.getColumnC(), dataR.getVaporAbv());
                chartPanelTime.setChart(cTime.getChart());
                //----------------------------------------
            }
        });
        stopRecordingButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                readIn = false;
            }
        });
        oG.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {

                System.out.println(oG.getSelectedItem().toString());
                String tmpS = oG.getSelectedItem().toString();
                Double og = TempCorrections.GetSG(Double.valueOf(tmpS), oT.getSelectedItem().toString());
                tmpS = tG.getSelectedItem().toString();
                Double tg = TempCorrections.GetSG(Double.valueOf(tmpS), tT.getSelectedItem().toString());
                DecimalFormat df1 = new DecimalFormat("#.####");
                wortAbv.setText(String.valueOf(df1.format((og - tg) * 105 * 1.25)));
            }
        });
        chartRange.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Data.timeSpan = chartRange.getSelectedItem().toString();
                double[][] data = new double[][]{{1.0, 3.0, 3.0, 5.0, 5.0, 5.0, 3.0, 3.0}, {7.0, 7.0, 7.0, 8.0, 8.0, 8.0, 10.0, 10.0}, {4.0, 3.0, 2.0, 3.0, 6.0, 3.0, 4.0, 3.0}};
                cArea.updateChart(data);
                chartPanelArea.setChart(cArea.getChart());
                chartPanelPie.setChart(cPie.getChart2());
                chartPanelPie.validate();
                //---------------------------------------- ColumnT vs time
                ReadInData dataR = new ReadInData();
                dataR.Read();
                cTime.updateChart(dataR.getmilliTime(), dataR.getColumnC(), dataR.getVaporAbv());
                chartPanelTime.setChart(cTime.getChart());
                //----------------------------------------
            }
        });
        bottle.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Data.bottleS = bottle.getSelectedItem().toString();
                BottleCalcs bCalc = new BottleCalcs();
            }
        });
        boilerTemp.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Data.boilTempS = boilerTemp.getSelectedItem().toString();
            }
        });
        measAbv.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Data.measAbvS = measAbv.getSelectedItem().toString();
                if (Double.valueOf(Data.boilTempS) >= -1 &
                        Double.valueOf(Data.measAbvS) >= -1 &
                        Double.valueOf(Data.distTemp) >= -1 &
                        Double.valueOf(oG.getSelectedItem().toString()) >= -1 &
                        Double.valueOf(tG.getSelectedItem().toString()) >= -1 &
                        Double.valueOf(oT.getSelectedItem().toString()) >= -1 &
                        Double.valueOf(tT.getSelectedItem().toString()) >= -1 &
                        Double.valueOf(Data.bottleS) >= -1
                        ) {
                    corrAbv.setText(String.valueOf(runInfo.TempCorrections.GetABV(Double.valueOf(Data.measAbvS), Data.distTemp)));
                    Data.corrAbvS = corrAbv.getText();
                }
            }
        });
        distTemp.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Data.distTemp = distTemp.getSelectedItem().toString();
                if (Double.valueOf(Data.boilTempS) >= -1 &
                        Double.valueOf(Data.measAbvS) >= -1 &
                        Double.valueOf(Data.distTemp) >= -1 &
                        Double.valueOf(oG.getSelectedItem().toString()) >= -1 &
                        Double.valueOf(tG.getSelectedItem().toString()) >= -1 &
                        Double.valueOf(oT.getSelectedItem().toString()) >= -1 &
                        Double.valueOf(tT.getSelectedItem().toString()) >= -1 &
                        Double.valueOf(Data.bottleS) >= -1
                        ) {
                    corrAbv.setText(String.valueOf(runInfo.TempCorrections.GetABV(Double.valueOf(Data.measAbvS), Data.distTemp)));
                    Data.corrAbvS = corrAbv.getText();
                }
            }
        });
        flowRateVol.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                DecimalFormat df = new DecimalFormat("###.#");
                flowRate.setText(String.valueOf(df.format(Double.valueOf(flowRateVol.getSelectedItem().toString()) / Double.valueOf(flowRateTime.getSelectedItem().toString()) / 60.0)));
                Data.flowRate = flowRate.getText();
            }
        });
        flowRateTime.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                DecimalFormat df = new DecimalFormat("###.#");
                Double tempN = Double.valueOf(flowRateVol.getSelectedItem().toString()) * 60.0;
                Double tempD = Double.valueOf(flowRateTime.getSelectedItem().toString());
                double output = tempN / tempD;
                output = Double.valueOf(df.format(output));
                flowRate.setText(String.valueOf(output));
                Data.flowRate = flowRate.getText();
            }
        });
    }

    static String getTimeSpan() {
        Hashtable hashtable = new Hashtable();
        hashtable.put("5 min", "5"); //adding value to Hashtable
        hashtable.put("10 min", "10");
        hashtable.put("20 min", "20");
        hashtable.put("30 min", "30");
        hashtable.put("45 min", "45");
        hashtable.put("1 hr", "60");
        hashtable.put("2 hr", "120");
        hashtable.put("5 hr", "300");
        hashtable.put("10 hr", "600");
        hashtable.put("1 day", "1440");
        hashtable.put("2 days", "2880");
        hashtable.put("3 days", "4320");
        hashtable.put("4 days", "5760");
        hashtable.put("5 days", "7200");
        hashtable.put("6 days", "8640");
        hashtable.put("7 days", "10080");
        hashtable.put("8 days", "11520");
        hashtable.put("10 days", "14400");
        hashtable.put("30 days", "43200");
        String output = (String) hashtable.get(Data.timeSpan);
        return output;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("MainGui");
        frame.setContentPane(new MainGui().ideaGui2);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public void setData(MainGui data) {
    }

    public void getData(MainGui data) {
    }

    public boolean isModified(MainGui data) {
        return false;
    }

    private void temperature() {

        FileDialog d = new FileDialog(frame, "title", FileDialog.LOAD);
        d.setDirectory("C:");
        d.show();
        d.getFile();
        String file = d.getDirectory() + d.getFile();
//        filePath.setText(file);
        System.out.println(d.getDirectory() + d.getFile());

        ensureEventThread();
        Runnable readRun = new Runnable() {
            public void run() {
                long startTime = System.currentTimeMillis();
                long currentTime;
                TemperatureSensorPhidget tempsensor;
                try {
                    tempsensor = new TemperatureSensorPhidget();
                    tempsensor.openAny();
                    System.out.println("waiting for TemperatureSensor attachment...");
                    tempsensor.waitForAttachment();
                    tempsensor.setTemperatureChangeTrigger(0, 0.2);
                    tempsensor.setThermocoupleType(0, TemperatureSensorPhidget.PHIDGET_TEMPERATURE_SENSOR_J_TYPE);
                    System.out.println("captured TemperatureSensor attachment.");
                    while (Data.programRunning) {
                        currentTime = System.currentTimeMillis();
                        Data.timeS = String.valueOf(((currentTime - startTime) / 1000.0));
                        GetTemps(tempsensor, startTime);
                        try {
                            Thread.sleep((long) 1000);            // sleep for X ms
                        } catch (InterruptedException e) {
                            int unableToSleep = 1;
                        }
                    }
                } catch (PhidgetException e2) {
                    e2.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("No longer measureing temperature ------------------------------------");
            }
        };
        tempThread = new Thread(readRun);
        tempThread.start();
    }

    public void GetTemps(TemperatureSensorPhidget tempsensor, Long startTime) throws PhidgetException, IOException {
        final double calibration = 0.3;
        columnDC = tempsensor.getTemperature(0) - calibration;
        ambientDC = tempsensor.getAmbientTemperature() - calibration;
        columnDF = columnDC * 9 / 5 + 32;
        ambientDF = ambientDC * 9 / 5 + 32;
        DecimalFormat df = new DecimalFormat("###.###");
        columnDC = Double.valueOf(df.format(columnDC));
        ambientDC = Double.valueOf(df.format(ambientDC));
        columnDF = Double.valueOf(df.format(columnDF));
        ambientDF = Double.valueOf(df.format(ambientDF));
        double runningTime = (1.0 / 1000.0) * (1.0 / 60.0) * (System.currentTimeMillis() - startTime);
        Data.milliTime = System.currentTimeMillis();
        Data.timeS = String.valueOf(runningTime);
        double tempChange = columnDC - lastWrittenTemp;
        if (Math.abs(tempChange) >= minTempChangeForWrite ||
                lastWrittenBoilTemp.contentEquals(Data.boilTempS) ||               // != Data.boilTempS ||
                lastWrittenBottleNum.contentEquals(Data.bottleS) ||                // != Data.bottleS ||
                lastWrittenAbv.contentEquals(Data.corrAbvS)                        // != Data.corrAbvS
                ) {
            lastWrittenTemp = columnDC;
            lastWrittenBoilTemp = boilerSC;
            lastWrittenBottleNum = bottleNumS;
            lastWrittenAbv = corrAbvS;
            Writer.WriteData(readIn, runningTime);
        }
        setTempTextSafe();
    }

    private void setTempTextSafe() {
        Runnable r = new Runnable() {
            public void run() {
                VaporAbv vAbv = new VaporAbv(String.valueOf(columnDC));
                try {
                    setColumnC(String.valueOf(columnDC));
                    setColumnF(String.valueOf(columnDF));
                    setAmbientC(String.valueOf(ambientDC));
                    setAmbientF(String.valueOf(ambientDF));
                    Data.tempTC = columnDC;
                    Data.tempTF = columnDF;
                    Data.tempAC = ambientDC;
                    Data.tempAF = ambientDF;
                    Data.vaporAbvS = vAbv.getVaporAbv();
                    setVaporAbv(Data.vaporAbvS);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        };
        SwingUtilities.invokeLater(r);
    }

    private void ensureEventThread() {
        if (SwingUtilities.isEventDispatchThread()) {
            return;
        }
        throw new RuntimeException("file");
    }

    private void setReadText(String text) {
        ensureEventThread();
    }

}
